﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Graphics.PackedVector;
using PolyVoxCore;

namespace DKE_Kinect.Entwicklung.PolyVox
{
    /// <summary>
    /// Enum für mögliche "Dickestufen" des Pinsels
    /// </summary>
    public enum VoxelThickness
    {
        /// <summary>
        /// Draw non solid blocks / delete blocks
        /// </summary>
        none,
        /// <summary>
        /// draw the smallest possible blocks
        /// </summary>
        thin,
        /// <summary>
        /// draw medium blocks
        /// </summary>
        medium,
        /// <summary>
        /// draw the thickest blocks
        /// </summary>
        thick
    }
    /// <summary>
    /// Klasse für den aktuelle genutzen Voxel (Farbe/Dichte)
    /// </summary>
    public class Voxel
    {
        private static MaterialDensityPair62 pVoxel;
        private static bool pColorsLoaded = false;
        private static Vector4[] pCData;

        /// <summary>
        /// Gets the colors.
        /// </summary>
        public static Vector4[] Colors
        {
            get { return pCData; }
        }

        /// <summary>
        /// Gets the current voxel.
        /// </summary>
        public static MaterialDensityPair62 CurrentVoxel
        {
            get { return pVoxel; }
        }

        /// <summary>
        /// Initialize the Voxel.
        /// </summary>
        public void Initialize()
        {
            pVoxel = new MaterialDensityPair62(0, 0);
            pCData = new Vector4[64];
        }

        /// <summary>
        /// Initializes the Voxel with the colorPalette.
        /// </summary>
        /// <param name="colorP">The color Palette.</param>
        public static void Initialize(Texture2D colorP)
        {
            pVoxel = new MaterialDensityPair62(0, 0);
            pCData = new Vector4[64];
            Voxel.loadColors(colorP);
        }
        /// <summary>
        /// Loads the colors.
        /// </summary>
        /// <param name="colorP">The colorPalette.</param>
        public static void loadColors(Texture2D colorP)
        {

            Byte4[] _data = new Byte4[colorP.Width * colorP.Height];
            colorP.GetData<Byte4>(_data);
            for (int i = 0; i < 64; i++)
            {
                pCData[i] = _data[i].ToVector4();
            }
            pColorsLoaded = true;
        }
        /// <summary>
        /// Sets the density.
        /// </summary>
        /// <param name="density">The density.</param>
        public static void SetDensity(byte density)
        {
            pVoxel.setDensity(density);
        }
        /// <summary>
        /// Sets the density.
        /// </summary>
        /// <param name="t">Density from enum</param>
        public static void SetDensity(VoxelThickness t)
        {
            switch (t)
            {
                case (VoxelThickness.none):
                    {
                        pVoxel.setDensity(0);
                        break;
                    }
                case (VoxelThickness.thick):
                    {
                        pVoxel.setDensity(3);
                        break;
                    }
                case (VoxelThickness.thin):
                    {
                        pVoxel.setDensity(1);
                        break;
                    }
                case (VoxelThickness.medium):
                    {
                        pVoxel.setDensity(2);
                        break;
                    }

            }
        }

        /// <summary>
        /// Sets the color.
        /// </summary>
        /// <param name="c">color to be set</param>
        public static void SetColor(Color c)
        {
            if (pColorsLoaded)
            {
                Vector4 _color = c.ToVector4();
                _color = Vector4.Multiply(_color, 255);
                byte matchingColor = 0;
                float maxDist = 585225;
                for (byte i = 0; i < 64; ++i)
                {
                    float dist = Vector4.DistanceSquared(_color, pCData[i]);
                    if (dist < maxDist)
                    {
                        maxDist = dist;
                        matchingColor = i;
                    }
                }
                Voxel.SetColor(matchingColor);
                return;
            }
            Voxel.SetColor(0);
        }

        /// <summary>
        /// Sets the color.
        /// </summary>
        /// <param name="color">The colorindex from our palette.</param>
        public static void SetColor(byte color)
        {
            pVoxel.setMaterial(color);
        }
    }
}
   
